import pandas as pd
import numpy as np
def data_preprocessing(path):
    data = pd.read_csv(path)
    # data.drop_duplicates(inplace=True)
    # print(data.isnull().sum())

# #对于分类变量（dtype 为 object），使用众数填充缺失值
# 对于数值变量，使用中位数填充缺失值
# 增加了效率优化（跳过无缺失值的列）和鲁棒性检查（防止空众数）
    for col in data.columns:
        if data[col].isnull().sum() == 0:
            continue  # 跳过无缺失值的列，提升效率
            #通过 isnull().sum() 快速判断该列是否存在缺失值,若没有缺失值则直接跳过.

        # 处理分类变量（dtype为object）
        if data[col].dtype == 'object':
            # 获取众数（最频繁出现的值），并处理可能为空的情况
            mode_value = data[col].mode()[0] if not data[col].mode().empty else ''
            data[col].fillna(mode_value, inplace=True)   #增加了鲁棒性检查：if not data[col].mode().empty
                                        #防止某些极端情况下（如全为缺失值）众数计算结果为空
        # 处理数值变量
        else:
            median_value = data[col].median()            #使用中位数填充数值型缺失值
            data[col].fillna(median_value, inplace=True) #中位数比均值更稳健，不易受极端值影响
    return data


def handle_outliers(data, columns=None, threshold=3):
    """
    处理数据中的异常值
    :param data: 输入的 DataFrame
    :param columns: 需要处理的列名列表，如果为 None，则处理所有数值列
    :param threshold: Z-score 阈值，默认值为 3
    :return: 处理后的 DataFrame
    """
    # 如果用户未指定列，则自动选择所有数值类型的列
    if columns is None:
        columns = data.select_dtypes(include=[np.number]).columns

    # 遍历选定的每一列进行异常值处理
    for col in columns:
        # 计算当前列每个数据点的Z-score（距离均值的标准差倍数）
        z_scores = np.abs((data[col] - data[col].mean()) / data[col].std())
        # 过滤掉Z-score超过阈值的行，保留正常数据
        data = data[z_scores < threshold]

    # 返回处理后的DataFrame，异常值已被删除
    return data

    # return data



if __name__ == '__main__':
    data = data_preprocessing('../data/train.csv')
    # print(data.head(5))
    # print(data.info())
    # print(type(data))
# 处理异常值
    data = handle_outliers(data)